Release 10.1A: OpenEdge Development:
Progress 4GL Handbook


Looking at preprocessor values in the Code Preview

The first statement already looks pretty strange:

{&OPEN-QUERY-CustQuery} 

What’s that all about? A name enclosed in braces and preceded by an ampersand tells you this is a Progress preprocessor value. You are probably familiar with preprocessor values from other languages you’ve used. It is nothing more than a substitution string. It’s defined up near the beginning of the procedure file, and everywhere it occurs in the 4GL code, the Progress syntax analyzer replaces it with the string it’s been defined to represent. That way, you (or the AppBuilder) can define a commonly used string of code once and use it multiple times in your procedure.

The AppBuilder generates the definition of this preprocessor value. Normally you don’t need to look at it, so it’s in a special section that isn’t displayed along with the rest of your code sections.

To look at the preprocessor definition:

  1. Return to the AppBuilder main window and press F5 or select Compile Code Preview from the menu. The Code Preview dialog box appears and shows all the code for the whole procedure.
  2. Scroll down in this dialog box to the section marked Preprocessor Definitions to find the definition of OPEN-QUERY-CustQuery, as shown in Figure 4–4.
  3. Figure 4–4: Preprocessor definition in the Code Preview window

&Scoped-define means that this definition is scoped to just this procedure file, rather than being available to any other source files that are associated with this one. From this line you see that the preprocessor OPEN-QUERY-CustQuery is defined to represent the text OPEN QUERY CustQuery FOR EACH Customer SHARE-LOCK. In later chapters you’ll explore the differences between defining and opening a query on a table and just retrieving the data using a FOR EACH statement by itself. For now it’s enough to understand that the query named CustQuery defines the set of data to be retrieved, the OPEN QUERY statement starts the retrieval, and then other statements that you’ll see next actually walk through the data row by row. The query definition itself is in another part of the AppBuilder-generated code, and just says DEFINE QUERY CustQuery FOR Customer.

Positioning within the query

The first statement opens that Customer query and sets you up to retrieve and display each of the Customer records in turn. Now look at the next statement:

GET FIRST CustQuery. 

This statement retrieves the first Customer record using the query CustQuery.

Moving on, you see a DISPLAY statement, which should be familiar to you. It has an IF-THEN construct in front of it that you haven’t seen before, but like most Progress 4GL statements, it’s self-explanatory. If the query turns out to be empty, or if you’ve reached the end of it, then you don’t want to try to display anything. The phrase IF AVAILABLE Customer checks for that:

IF AVAILABLE Customer THEN  
    DISPLAY Customer.CustNum Customer.Name Customer.Address Customer.City  
          Customer.State  
      WITH FRAME CustQuery IN WINDOW CustWin. 

Because a field name might occur in more than one table used in the procedure, the AppBuilder puts the table name in front of each field name, as in Customer.CustNum. This is a good practice for you to follow in the code you write unless your field names are all guaranteed to be unique.

The end of the DISPLAY statement has a qualifier you didn’t see in previous chapters either, WITH FRAME CustQuery. But you can certainly tell what it does. Chapter 2, "Using Basic 4GL Constructs," explains that Progress uses frames to define different display areas, and that each field and block of code is associated with a frame. If you don’t name the frames yourself, you get default frames. If you need to, you can give each frame a name and specify that frame in a DISPLAY statement. Then Progress knows exactly where each displayed field or other object should go. You renamed your window’s default frame CustQuery earlier, and here you see that name being used. And remember the AppBuilder uses the same name for the frame’s default query.

The second qualifier is understandable, too. If your procedure happened to define more than one window, then you would have to tell it which frames go in which window. Here the code makes that explicit, by appending the phrase IN WINDOW CustWin.

So apart from these qualifiers this statement should look familiar. Now look at the next statement:

ENABLE Customer.CustNum Customer.Name Customer.Address Customer.City  
         Customer.State OrderBrowse  
      WITH FRAME CustQuery IN WINDOW CustWin. 

Not surprisingly, this statement enables each of the fields for data entry, so that you could make changes to a record and then save it. Also it enables the browse control itself so that you can scroll it up and down. At this time, you won’t actually add a Save button to this window to let you save changes (you’ll do that in Chapter 16 "Updating Your Database and Writing Triggers").

Next is another preprocessor value:

{&OPEN-BROWSERS-IN-QUERY-CustQuery} 

If you do a Code Preview again (or refer to Figure 4–4) you can see that this value represents the statement OPEN QUERY OrderBrowse FOR EACH Order OF Customer NO-LOCK INDEXED-REPOSITION. You’ll get to details like NO-LOCK versus SHARE-LOCK and what INDEXED-REPOSITION means in Chapter 12, " Using the Browse Object." Otherwise, you should recognize this as the query you built in the Query Builder when you dropped the browse control onto the window.

The final executable statement is:

VIEW CustWin. 

This statement tells Progress at run time to make the window visible.

And finally, as you learned in the Chapter 3, "Running Progress 4GL Procedures," every internal procedure must end with an END PROCEDURE statement:

END PROCEDURE. 

This is all the code that’s needed to make all the things happen that you saw when you ran the window. It opens two different queries representing a parent-child relationship between Customers and Orders. It displays and then enables the Customer fields and the Order browse. And it views the window itself. All this happens in about ten lines of 4GL code. And you didn’t have to write any of it yourself.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095